/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.xeerkat.xmpp.server.db;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import org.milowski.db.DBConnection;
import org.milowski.db.DBIterator;
import org.milowski.db.DBObject;
import org.milowski.db.DBQueryHandler;
import org.milowski.db.DBResultConstructor;
import org.milowski.db.DBUpdateHandler;
import org.milowski.db.Slot;
import org.xeerkat.xmpp.ID;

/**
 *
 * @author alex
 */
public class Contact extends DBObject<XMPPDB> {

   public enum Subscription {
      None(0),
      From(1),
      To(2),
      Both(3);
      
      int value;
      Subscription(int value) {
         this.value = value;
      }
      
      public int getValue() { return value; }
      public String toString() {
         switch (value) {
            case 0: return "none";
            case 1: return "from";
            case 2: return "to";
            case 3: return "both";
         }
         return null;
      }
      static Subscription fromInt(int value) {
         switch (value) {
            case 0: return None;
            case 1: return From;
            case 2: return To;
            case 3: return Both;
         }
         throw new IllegalArgumentException("Invalid subscription value "+value);
      }
      public static Subscription fromString(String value) {
         if (value.equals("none")) {
            return None;
         } else if (value.equals("from")) {
            return From;
         } else if (value.equals("to")) {
            return To;
         } else if (value.equals("both")) {
            return Both;
         } else {
            throw new IllegalArgumentException("Invalid subcriptin value: "+value);
         }
      }
              
   }
   
   
   
   public enum Ask {
      None(0),
      SubscribeUnsent(1),
      Subscribe(2);
      
      int value;
      Ask(int value) {
         this.value = value;
      }
      
      public int getValue() { return value; }
      static Ask fromInt(int value) {
         switch (value) {
            case 0: return None;
            case 1: return SubscribeUnsent;
            case 2: return Subscribe;
         }
         throw new IllegalArgumentException("Invalid ask value "+value);
      }
      public String toString() {
         switch (value) {
            case 0: return "none";
            case 1: return "subscribe-unsent";
            case 2: return "subscribe";
         }
         return null;
      }
      
      public static Ask fromString(String value) {
         if (value.equals("none")) {
            return None;
         } else if (value.equals("subcribe-unsent")) {
            return SubscribeUnsent;
         } else if (value.equals("subscribe")) {
            return Subscribe;
         } else {
            throw new IllegalArgumentException("Invalid ask value: "+value);
         }
      }
      
   }

   User user;
   ID xmppid;
   Subscription subscription;
   Ask ask;
   String name;
   
   public Contact(XMPPDB db,int id,User user,ID xmppid,Subscription subscription,Ask ask,String name)
   {
      super(db,id);
      this.user = user;
      this.xmppid = xmppid;
      this.subscription = subscription;
      this.ask = ask;
      this.name = name;
   }      
   
   public User getUser() {
      return user;
   }

   public Subscription getSubscription() {
      return subscription;
   }

   public void setSubscription(Subscription subscription) {
      this.subscription = subscription;
   }

   public Ask getAsk() {
      return ask;
   }

   public void setAsk(Ask ask) {
      this.ask = ask;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public ID getXMPPID() {
      return xmppid;
   }

   public boolean delete()
      throws SQLException
   {
      DBConnection connection = db.getConnection();
      try {
         connection.deleteById(XMPPDB.STATEMENT_DELETE_CONTACT_CONTACT_GROUPS, id);
         return connection.deleteById(XMPPDB.STATEMENT_DELETE_CONTACT, id)>0;
      } finally {
         db.release(connection);
      }
   }
   
   public boolean update() 
      throws SQLException
   {
      DBConnection connection = db.getConnection();
      try {
         return connection.update(XMPPDB.STATEMENT_UPDATE_CONTACT, new DBUpdateHandler() {
            public void prepare(PreparedStatement s)
               throws SQLException
            {
               s.setInt(1,subscription.getValue());
               s.setInt(2,ask.getValue());
               s.setString(3,name);
               s.setInt(4,id);
            }
         })>0;
      } finally {
         db.release(connection);
      }
   }
   
   public void addGroup(final Group group)
      throws SQLException
   {
      DBConnection connection = db.getConnection();
      try {
         connection.update(XMPPDB.STATEMENT_ADD_CONTACT_TO_GROUP, new DBUpdateHandler() {
            public void prepare(PreparedStatement s)
               throws SQLException
            {
               s.setInt(1,user.getId());
               s.setInt(2,id);
               s.setInt(3,group.getId());
            }
         });
      } finally {
         db.release(connection);
      }
   }
   
   public void removeGroup(final Group group)
      throws SQLException
   {
      DBConnection connection = db.getConnection();
      try {
         connection.update(XMPPDB.STATEMENT_ADD_CONTACT_TO_GROUP, new DBUpdateHandler() {
            public void prepare(PreparedStatement s)
               throws SQLException
            {
               s.setInt(1,id);
               s.setInt(2,group.getId());
            }
         });
      } finally {
         db.release(connection);
      }
   }
   
   public void removeAllGroups()
      throws SQLException
   {
      DBConnection connection = db.getConnection();
      try {
         connection.update(XMPPDB.STATEMENT_DELETE_CONTACT_FROM_ALL_GROUPS, new DBUpdateHandler() {
            public void prepare(PreparedStatement s)
               throws SQLException
            {
               s.setInt(1,id);
            }
         });
      } finally {
         db.release(connection);
      }
   }
   
   public Iterator<String> getGroupNames()
      throws SQLException
   {
      final Slot<DBIterator<String>> result = new Slot<DBIterator<String>>();
      final DBConnection connection = db.getConnection();
      try {
         connection.query(XMPPDB.STATEMENT_CONTACT_GROUP_NAMES, new DBQueryHandler() {
            public void prepare(PreparedStatement s)
               throws SQLException
            {
               s.setInt(1,id);
            }
            public boolean shouldClose() {
               return false;
            }
            public void onResults(ResultSet set)
            {
               result.set(new DBIterator<String>(set,new DBResultConstructor<String>() {
                  public String newInstance(ResultSet set) 
                     throws SQLException
                  {
                     return set.getString(1);
                  }
               },db,connection));
            }
         });
         return result.get();
      } catch(SQLException ex) {
         db.release(connection);
         throw ex;
      }
   }
   
}
